home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c++
- Path: netcom.com!marnold
- From: marnold@netcom.com (Matt Arnold)
- Subject: Re: C++ Shortcomings ?
- Message-ID: <marnoldDoCpn0.Axu@netcom.com>
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
- References: <31488E8D.167E@aw.sgi.com> <4iaqch$moh@B1FF.mindspring.com> <31493CDA.41C6@aw.sgi.com>
- Date: Sat, 16 Mar 1996 08:16:11 GMT
- Sender: marnold@netcom2.netcom.com
-
- Emmanuel Mogenet <mgix@aw.sgi.com> writes:
-
- >Justin Rudd wrote:
- >>
- >> Emmanuel Mogenet <mgix@aw.sgi.com> wrote:
- >>
- >> >In other word, make portions of the interface to a class private to
- >> >only some classes.
- >>
- >> > 1. Wouldn't that be nicer than the friend mechanism that cracks
- >> > open a class a spill its guts ?
- >> > 2. Is there a clean way to achieve in today's C++ standard ?
- >> > 3. Or is it a bad idea altogether ?
- >>
- >I guess my post was messy and unclear.
- >What I want is to be able for a class A to tell:
-
-
- >class A
- >{
- >restricted B:
- > void DoSomething();
- >}
-
- >This means: Ok, the method A::DoSomething is public, but not
- >public for everybody. Only members of class B can have access to
- >this method.
-
- >It's a bit like the friend operator, but instead of spilling
- >everything to the friend, we just let him peep through a specialized window.
-
- Why not make a third "proxy" class C to represent the normally private parts
- of A you would like B to have access to.
-
- For example, say you have a class A with 10 private member functions. You
- want B to access half of them without being able to access the other half.
- So, you make a class C that is a friend of A. C has a pointer to some A
- and C's interface duplicates the half of A's interface you want to be
- "semi-public" (when C::SomeMember() is called, it simply forwards the
- call to A::SomeMember()). B, in turn, is a friend of C, so it can access
- C's interface. This way, no one but B can call the select private members
- of A (via C!). And, B only has access to just those select members you
- choose to make part of C's interface.
-
- >> >2. Pointer type manipulation
- >> >-----------------------------
- >>
- >> >A very disappointing thing in C++ (unless I am mistaken and it is actually
- >> >possible to do so) is the following situation:
- >>
- >> >If A is a class, then most operations on A can be redefined.
- >> >Because A is a full blown type.
- >>
- >> >Sadly, the same can not be said about A* (type: pointer to A).
- >>
- >> >Even though A* is a type, none of its default manipulations
- >> >can be redefined.
- >>
- >> >Example: You can tell C++, that you want to gain control of the
- >> >situation whenever an object of type A is duplicated.
- >>
- >> >You do so by redefining the default copy constructor and the default
- >> >assignment operator.
- >>
- >> >But can you tell C++ that you want to gain control whenever a pointer of
- >> >A* is duplicated ? Why can't I redefine the copy constructor for the type A* ?
-
-
- You can do this if you use a smart pointer for A (a class that acts like a
- pointer). You smart pointer class can have any kind of overloading you like.
-
- You cannot overload the literal type A*, of course. Is this what you are
- complaining about? If so, what is wrong with a smart pointer class?
-
-
- >> >In my way of looking at thing, that'd be a *great* way of doing clean reference
- >> >counting, instead of half-baked method using a redefinition of operator->.
- >>
-
- What do you mean by half-baked?
-
- >> >Comments ?
- >>
- >> Ok...so you are saying you can do something like this...
-
- >What I meant was: I would like to be able to redefine the default
- >copy constructor for pointers.
-
- >In other words, when I write:
- >class A
- >{
- >};
-
- >main()
- >{
- > A *a;
- > B *b;
-
- > a=new A();
- > b=a;
- >}
-
- >I want the compiler to trap this for me and give me control.
- >What I really want the compiler to do is:
-
- >main()
- >{
- > 1. Call the constructor of object A* (that's what we do. We build an A*)
- > 2. Call the constructor of object B*
-
- > Call the constructor for object A* (to temporarily store the result of new)
- > Call the assignment method (to assign the result of new to a)
- > Call the assignment operator (to assign the value of a to b)
- >
- >}
-
- >Another way to put it:
- >I would like to be able to write
-
- >class A*
- >{
- > A*(); // To build a pointer to A
- > A*(const A*&) // To build an A* from another A*
- > ~A*(); // To get hold of what happens when a pointer to A goes out of scope
-
- > A* operator=(const A*&); // To redefine assignment
- >
- >}
-
-
- >All this complicated mechanics would allow to build
- >industrial-strength reference counting on objects.
-
-
- You *can* build good reference counting on objects, with smart pointers.
- Assuming a properly implemented ref_ptr class, the code might look like
- this...
-
- main()
- {
- ref_ptr<A> a;
- ref_ptr<B> b;
-
- a=new A();
- b=a;
- }
-
- This syntax is pretty close to what you want.
-
- Plus, somewhere, you get to write...
-
-
- template <class T>
- ref_ptr<T>& ref_ptr<T>::operator=(T* pt)
- {
- // do assignment from a raw pointer however you like
- }
-
- template <class T>
- ref_ptr<T>& ref_ptr<T>::operator=(const ref_ptr<T>& pt)
- {
- // do assignment from another pointer object however you like
- }
-
-
- The book "More Effective C++" has a pretty good discussion on reference
- counted objects with sample code for a reference-counted string class.
- Smart pointers are also discussed.
-
-
- Regards,
- -------------------------------------------------------------------------
- Matt Arnold | | ||| | |||| | | | || ||
- marnold@netcom.com | | ||| | |||| | | | || ||
- Boston, MA | 0 | ||| | |||| | | | || ||
- 617.389.7384 (h) 617.576.2760 (w) | | ||| | |||| | | | || ||
- C++, MIDI, Win32/95 developer | | ||| 4 3 1 0 8 3 || ||
- -------------------------------------------------------------------------
-